#include "net_music.h"
#include "httpapi.h"
#include <string.h>

#include "esp_log.h"
#include "esp_err.h"

#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"
#include "cjson.h"

static const char *TAG = "NET_MUSIC";

EXT_RAM_ATTR char music_url[128];//组装url

#define GET_JSON_VALUE(x,y) cJSON *y = cJSON_GetObjectItem(x, #y);ASSER1(y)
#define ASSER1(x) do{if(x == NULL)\
        {\
            ESP_LOGI(TAG, "%s error",#x);\
            return;\
        }}while(0)


/**
 * @brief 歌曲链表增加
 *
 * @param list 歌曲链表
 * @param music 歌曲
 */
void song_list_add(SongNode **list, music_info *i)
{
    SongNode *node = (SongNode *)malloc(sizeof(SongNode));
    if (node == NULL)
    {
        return;
    }
    node->music = i;

    if (*list == NULL)
    {
        *list = node;
        (*list)->next = node;
        (*list)->prev = node;
    }
    else
    {
        node->prev = (*list)->prev;
        node->next = *list;
        (*list)->prev->next = node;
        (*list)->prev = node;
    }
}
void song_list_free(SongNode **list)
{
    if (*list == NULL)
    {
        return;
    }
    SongNode *p = *list;

    do
    {
        SongNode *q = p;
        music_info_free(p->music);
        p = p->next;
        free(q);
    }
    while (p->next != *list);
    music_info_free(p->music);
    free(p);
    *list = NULL;
}

SongNode *song_list_next(SongNode *now)
{
    if (now == NULL)
    {
        return NULL;
    }
    return now->next;
}

SongNode *song_list_prev(SongNode *now)
{
    if (now == NULL)
    {
        return NULL;
    }
    return now->prev;
}

/**
 * @brief 释放歌曲信息
 *
 * @param m
 */
void music_info_free(music_info *m)
{
    free(m->name);
    free(m->artist);
    free(m);
}

/**
 * @brief 新增一首歌
 *
 * @param id
 * @param name
 * @param artist
 * @return music_info*
 */
music_info *music_info_new(unsigned int id, char *name, char *artist)
{
    music_info *m = (music_info *)malloc(sizeof(music_info));
    if (m == 0)
    {
        ESP_LOGE(TAG, "music info malloc error");
    }
    m->id = id;
    int len = strlen(name);
    m->name = (char *)malloc(len + 1);
    strcpy(m->name, name);
    m->name[len] = 0;
    m->artist = artist;
    return m;
}

/**
 * @brief 解析歌单列表
 *
 * @param data
 * @param arg
 */
static void song_list_parse(char *data, void *arg)
{
    SongNode **head = (SongNode **)arg;

    cJSON *parse = cJSON_Parse(data);
    if (parse == NULL)
    {
        ESP_LOGE(TAG, "parse error %s", cJSON_GetErrorPtr());
        return;
    }
    cJSON *playlist = cJSON_GetObjectItem(parse, "playlist");
    ASSER1(playlist);
    cJSON *tracks = cJSON_GetObjectItem(playlist, "tracks");
    ASSER1(tracks);
    // 清空之前的歌曲清单
    song_list_free(head);
    int size = cJSON_GetArraySize(tracks);
    for (int i = 0; i < size; i++)
    {
        cJSON *track = cJSON_GetArrayItem(tracks, i);
        ASSER1(track);
        GET_JSON_VALUE(track, name);
        GET_JSON_VALUE(track, id);
        GET_JSON_VALUE(track, ar);
        int art_size = cJSON_GetArraySize(ar);
        int len = 0;
        for (int i = 0; i < art_size; i++)
        {
            cJSON *an = cJSON_GetArrayItem(ar, i);
            cJSON *anme = cJSON_GetObjectItem(an, "name");

            len += strlen(anme->valuestring) + 1;
        }
        char *art_name = (char *)malloc(len);
        art_name[len - 1] = 0;
        len = 0;
        for (int i = 0; i < art_size; i++)
        {
            cJSON *an = cJSON_GetArrayItem(ar, i);
            cJSON *anme = cJSON_GetObjectItem(an, "name");
            strcpy(art_name + len, anme->valuestring);
            len += strlen(anme->valuestring) + 1;
            art_name[len - 1] = ',';
        }
        art_name[len - 1] = 0;
        music_info *m = music_info_new(id->valueint, name->valuestring, art_name);
        ESP_LOGI(TAG, "name:%s\r\nid:%d\r\nart:%s", m->name, m->id, m->artist);
        song_list_add(head, m);
    }

    cJSON_Delete(parse); // 删除json对象

}


/**
 * @brief 获取歌单，同步，http_get会同步等待http接收完成
 *
 * @param id 歌单id
 * @param list 歌单列表
 */
int net_get_songlist(char *id, SongNode **list)
{
    //'热歌榜':'3778678','原创榜':2884035,'新歌榜':3779629,'飙升榜':19723756,'云音乐说唱榜':19723756
    sprintf(music_url, "/api/v6/playlist/detail?id=%s", id);
    return http_api_get("music.163.com", music_url, song_list_parse, list);
}


/**
 * @brief 查询歌曲信息
 *
 * @param data
 * @param arg
 */
static void search_music_info(char *data, void *arg)
{
    SongNode **head = (SongNode **)arg;
    cJSON *parse = cJSON_Parse(data);
    ASSER1(parse);
    cJSON *result = cJSON_GetObjectItem(parse, "result");
    ASSER1(result);
    cJSON *songs = cJSON_GetObjectItem(result, "songs");
    ASSER1(songs);
    // 清空之前的歌曲清单
    song_list_free(head);
    int size = cJSON_GetArraySize(songs);
    for (int i = 0; i < size; i++)
    {
        cJSON *song = cJSON_GetArrayItem(songs, i);
        ASSER1(song);
        cJSON *name = cJSON_GetObjectItem(song, "name");
        ASSER1(name);
        cJSON *id = cJSON_GetObjectItem(song, "id");
        ASSER1(id);
        GET_JSON_VALUE(song, artists);
        int art_size = cJSON_GetArraySize(artists);
        int len = 0;
        for (int i = 0; i < art_size; i++)
        {
            cJSON *an = cJSON_GetArrayItem(artists, i);
            cJSON *anme = cJSON_GetObjectItem(an, "name");

            len += strlen(anme->valuestring) + 1;
        }
        char *art_name = (char *)malloc(len);
        art_name[len - 1] = 0;
        len = 0;
        for (int i = 0; i < art_size; i++)
        {
            cJSON *an = cJSON_GetArrayItem(artists, i);
            cJSON *anme = cJSON_GetObjectItem(an, "name");
            strcpy(art_name + len, anme->valuestring);
            len += strlen(anme->valuestring) + 1;
            art_name[len - 1] = ',';
        }
        art_name[len - 1] = 0;
        // ESP_LOGI(TAG, "name:%s\r\nid:%d\r\nart:%s", name->valuestring, id->valueint, art_name);
        music_info *m = music_info_new(id->valueint, name->valuestring, art_name);
        ESP_LOGI(TAG, "name:%s\r\nid:%d\r\nart:%s", m->name, m->id, m->artist);
        song_list_add(head, m);
    }

    cJSON_Delete(parse); // 删除json对象
}

void net_search_music(char *msg, SongNode **list)
{
    sprintf(music_url, "/search/get/?src=lofter&type=1&filterDj=false&limit=10&offset=0&s=%s", msg);
    for (int i = 0; i < strlen(music_url); i++)
    {
        if (music_url[i] == ' ')
        {
            music_url[i] = '+';
        }
    }

    http_api_get("s.music.163.com", music_url, search_music_info, list);
}


static void get_music_url(char *data, void *arg)
{

}
void net_get_music_url(music_info *music, char **url)
{
    sprintf(music_url, "/song/media/outer/url?id=%d", music->id);
    http_api_get("music.163.com", music_url, get_music_url, (void *)url);
    if(*url != NULL)
    {
        ESP_LOGI(TAG, "music:%s art:%s url:%s", music->name, music->artist, *url);
    }
}



static void get_music_lyric(char *data, void *arg)
{
    
    cJSON *parse = cJSON_Parse(data);
    if (parse == NULL)
    {
        ESP_LOGE(TAG, "parse error %s", cJSON_GetErrorPtr());
        return;
    }
    GET_JSON_VALUE(parse,lrc);
    GET_JSON_VALUE(lrc,lyric);
    int len = strlen(lyric->valuestring);
    *((char**)arg) = (char*)malloc(len+1);
    char* lr = *((char**)arg);
    lr[len] = 0;
    strcpy(lr,lyric->valuestring);
    
    cJSON_Delete(parse); // 删除json对象
}

void net_get_music_lyric(music_info *music,char** lyric)
{
    sprintf(music_url, "/api/song/lyric?os=pc&id=%d&lv=-1&kv=-1&tv=-1", music->id);
    http_api_get("music.163.com", music_url, get_music_lyric, (void*)lyric);
}